﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Xml.Linq;
using Xceed.Wpf.Toolkit.PropertyGrid.Attributes;

//public class XmlDynamicProperties : ICustomTypeDescriptor
//{
//    private readonly Dictionary<string, object> _properties = new Dictionary<string, object>();
//    public XmlDynamicProperties(XElement element)
//    {
//        LoadFromXml(element);
//    }
//    public Dictionary<string, object> Properties => _properties;
//    private void LoadFromXml(XElement element)
//    {
//        foreach (var child in element.Elements())
//        {
//            if (child.HasElements)
//            {
//                // 如果子元素有更多子元素，则递归处理
//                _properties[child.Name.LocalName] = new XmlDynamicProperties(child);
//            }
//            else
//            {
//                // 否则直接添加属性
//                _properties[child.Name.LocalName] = child.Value;
//                child.Attributes().ToList().ForEach(attr =>
//                {
//                    // 处理属性
//                    _properties[attr.Name.LocalName] = attr.Value;
//                });
//            }
//        }
//    }

//    // 实现ICustomTypeDescriptor接口的方法
//    public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true);
//    public string GetClassName() => TypeDescriptor.GetClassName(this, true);
//    public string GetComponentName() => TypeDescriptor.GetComponentName(this, true);
//    public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true);
//    public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true);
//    public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true);
//    public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true);
//    public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true);
//    public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true);
//    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) => GetProperties();
//    public PropertyDescriptorCollection GetProperties()
//    {
//        var properties = new List<PropertyDescriptor>();
//        foreach (var prop in _properties)
//        {
//            properties.Add(new XmlDynamicPropertyDescriptor(prop.Key, prop.Value));
//        }
//        return new PropertyDescriptorCollection(properties.ToArray());
//    }
//    public object GetPropertyOwner(PropertyDescriptor pd) => this;
//}

//public class XmlDynamicPropertyDescriptor : PropertyDescriptor
//{
//    private readonly string _name;
//    [ExpandableObject]
//    private readonly object _value;
//    public XmlDynamicPropertyDescriptor(string name, object value)
//        : base(name, null)
//    {
//        _name = name;
//        _value = value;
//    }

//    public override Type ComponentType => typeof(XmlDynamicProperties);
//    public override bool IsReadOnly => false;
//    public override Type PropertyType => _value?.GetType() ?? typeof(string);

//    public override bool CanResetValue(object component) => false;
//    public override object GetValue(object component)
//    {
//        if (_value is XmlDynamicProperties props)
//        {
//            return props; // 返回嵌套的属性集
//        }
//        return _value;
//    }
//    public override void ResetValue(object component) { }
//    public override void SetValue(object component, object value)
//    {
//        if (component is XmlDynamicProperties dynamicProperties && value is XmlDynamicProperties newValue)
//        {
//            dynamicProperties.Properties[_name] = newValue;
//        }
//        else
//        {
//            ((XmlDynamicProperties)component).Properties[_name] = value;
//        }
//    }
//    public override bool ShouldSerializeValue(object component) => false;
//}


public class XmlDynamicProperties : ICustomTypeDescriptor
{
    private readonly XElement _element;
    private readonly Dictionary<string, (XmlDynamicProperties, bool)> _properties = new Dictionary<string, (XmlDynamicProperties, bool)>();
    public XmlDynamicProperties(XElement element)
    {
        _element = element;
        LoadFromXml(element);
    }

    private string GenerateUniquePropertyName(XElement element, string path, ref int index)
    {
        string namePart = $"{element.Name}_{index++}";
        return string.IsNullOrEmpty(path) ? namePart : $"{path}.{namePart}";
    }
    private void LoadFromXml(XElement element, string path = "")
    {
        int index = 0;
        foreach (var child in element.Elements())
        {
            var uniqueName = GenerateUniquePropertyName(child, path, ref index);

            var attributes = child.Attributes().ToDictionary(a => a.Name.LocalName, a => a.Value);

            if (child.HasElements)
            {
                // 如果子元素有更多子元素，则递归处理
                _properties[uniqueName] = (new XmlDynamicProperties(child), false);
            }
            else
            {
                _properties[uniqueName] = (new XmlDynamicProperties(child), true);
            }

        }

    }
    public PropertyDescriptorCollection GetProperties(Attribute[] attributes) => GetProperties();
    public PropertyDescriptorCollection GetProperties()
    {
        var properties = new List<PropertyDescriptor>();

        // 添加当前元素的属性作为属性
        foreach (var attribute in _element.Attributes())
        {
            properties.Add(new XmlAttributePropertyDescriptor(attribute));
        }
        int index = 0;

        // 添加子元素作为属性
        foreach (var child in _properties)
        {
            var uniqueName = GenerateUniquePropertyName(((XmlDynamicProperties)child.Value.Item1)._element, "", ref index);
            properties.Add(new XmlDynamicPropertyDescriptor(((XmlDynamicProperties)child.Value.Item1)._element, uniqueName,child.Value.Item2));

        }

        return new PropertyDescriptorCollection(properties.ToArray());
    }

    // 其他ICustomTypeDescriptor接口方法...
    public AttributeCollection GetAttributes() => TypeDescriptor.GetAttributes(this, true);
    public string GetClassName() => TypeDescriptor.GetClassName(this, true);
    public string GetComponentName() => TypeDescriptor.GetComponentName(this, true);
    public TypeConverter GetConverter() => TypeDescriptor.GetConverter(this, true);
    public EventDescriptor GetDefaultEvent() => TypeDescriptor.GetDefaultEvent(this, true);
    public PropertyDescriptor GetDefaultProperty() => TypeDescriptor.GetDefaultProperty(this, true);
    public object GetEditor(Type editorBaseType) => TypeDescriptor.GetEditor(this, editorBaseType, true);
    public EventDescriptorCollection GetEvents(Attribute[] attributes) => TypeDescriptor.GetEvents(this, attributes, true);
    public EventDescriptorCollection GetEvents() => TypeDescriptor.GetEvents(this, true);
    public object GetPropertyOwner(PropertyDescriptor pd) => this;
}

public class XmlDynamicPropertyDescriptor : PropertyDescriptor
{
    private readonly XElement _element;
    private bool isleaf = false;

    public XmlDynamicPropertyDescriptor(XElement element, string propertyName, bool isleafNode = false)
        : base(propertyName, null)
    {
        _element = element;
        isleaf = isleafNode;
    }

    public override Type ComponentType => typeof(XmlDynamicProperties);
    public override bool IsReadOnly => false;
    public override Type PropertyType =>  typeof(XmlDynamicProperties) ;

    public override bool CanResetValue(object component) => false;
    public override object GetValue(object component)
    {
        //if (_element.HasElements)
        //{
        return new XmlDynamicProperties(_element);
        //}
        //else
        //{
        //    return _element.Value;
        //}
    }
    public override void ResetValue(object component) { }
    public override void SetValue(object component, object value)
    {
        if (value is string strValue && !_element.HasElements)
        {
            _element.SetValue(strValue);
        }
    }
    public override bool ShouldSerializeValue(object component) => false;


    public override string Description => _element.Attribute("description")?.Value ?? "";
}

public class XmlAttributePropertyDescriptor : PropertyDescriptor
{
    private readonly XAttribute _attribute;

    public XmlAttributePropertyDescriptor(XAttribute attribute)
        : base(attribute.Name.LocalName, null)
    {
        _attribute = attribute;
    }

    public override Type ComponentType => typeof(XmlDynamicProperties);
    public override bool IsReadOnly => false;
    public override Type PropertyType => typeof(string);

    public override bool CanResetValue(object component) => false;
    public override object GetValue(object component) => _attribute.Value;
    public override void ResetValue(object component) { }
    public override void SetValue(object component, object value) => _attribute.SetValue(value.ToString());
    public override bool ShouldSerializeValue(object component) => false;

    public override string DisplayName => _attribute.Name.LocalName;

}